﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.ExtendedReflection.Utilities;
using Microsoft.ExtendedReflection.Metadata;
using System.IO;

namespace PexMeHelper
{
    /// <summary>
    /// Prepares list of PUTs 
    /// </summary>
    class PUTCommandGenerator
    {
        public static void GeneratePUTCommands(string assemblyName)
        {
            AssemblyEx assemblyEx;
            var result = ReflectionHelper.TryLoadAssemblyEx(assemblyName, out assemblyEx);
                
            if(!result)
            {
                Console.WriteLine("Assembly " + assemblyName + " not found!!!");
                return;
            }

            var outfilename = Path.Combine(Path.GetDirectoryName(assemblyName),
                Path.GetFileNameWithoutExtension(assemblyName) + ".cmd.txt");

            using (StreamWriter sw = new StreamWriter(outfilename))
            {
                //Traverse through each method
                foreach (var classdef in assemblyEx.TypeDefinitions)
                {
                    var namespacestr = classdef.Namespace;
                    foreach (var mdef in classdef.DeclaredInstanceMethods)
                    {
                        bool isPexMethod = false;
                        foreach (var attr in mdef.DeclaredAttributes)
                        {
                            if (attr.SerializableName.ToString().Contains("PexMethodAttribute"))
                            {
                                isPexMethod = true;
                                break;
                            }
                        }

                        if (isPexMethod)
                        {
                            StringBuilder sb = new StringBuilder();
                            sb.Append("pex.exe ");
                            sb.Append(assemblyEx.Location);
                            sb.Append(" /nf:");
                            sb.Append(namespacestr);
                            sb.Append(" /tf:");
                            sb.Append(classdef.ShortName.ToString() + "!");
                            sb.Append(" /mf:");
                            sb.Append(mdef.ShortName.ToString() + "!");
                            sb.Append(" /nor");                            
                            sb.Append(" /rn:");
                            sb.Append(classdef.ShortName.ToString() + "_" + mdef.ShortName.ToString());
                            sb.Append(" /fullmscorlib");
                            sw.WriteLine(sb.ToString());
                        }
                    }
                }
            }
        }
    }
}
